package com.jeesite.common.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.jeesite.common.service.ServiceException;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author mnd
 */
public class ValidationUtils {

    /**
     * 抛出错误信息，不赞成使用，如果本类的其他方法不能满足时，请手工抛出异常
     *
     * @param msg 错误信息
     */
    public static void error(String msg) {
        throw new ServiceException(msg);
    }

    /**
     * 抛出错误信息
     *
     * @param msg 错误信息
     */
    public static void error(Exception msg) {
        throw new ServiceException(msg);
    }

    /**
     * 校验参数是否符合给定条件, 不符合则提示错误信息
     *
     * @param condition 布尔条件
     * @param message   错误提示信息
     */
    public static void isTrue(boolean condition, String message) {
        if (!condition) {
            throw new ServiceException(message);
        }
    }

    /**
     * 校验object不为null, 是，则抛出异常，提示错误信息
     *
     * @param object  校验对象
     * @param message 错误信息
     */
    public static void notNull(Object object, String message) {
        isTrue(ObjUtil.isNotNull(object), message);
    }

    /**
     * 校验集合是否为非空
     *
     * @param collection 集合对象
     * @param message    错误信息
     */
    public static void notEmpty(Collection<?> collection, String message) {
        isTrue(CollUtil.isNotEmpty(collection), message);
    }

    /**
     * 校验集合是否为空
     *
     * @param collection 集合对象
     * @param message    错误信息
     */
    public static void assertEmpty(Collection<?> collection, String message) {
        isTrue(CollUtil.isEmpty(collection), message);
    }

    /**
     * 判断对象是否不相等
     *
     * @param o1  对象1
     * @param o2  对象2
     * @param msg 错误信息
     */
    public static void notEqual(Object o1, Object o2, String msg) {
        isTrue(ObjUtil.notEqual(o1, o2), msg);
    }

    /**
     * 判断对象是否不相等
     *
     * @param o1  对象1
     * @param o2  对象2
     * @param msg 错误信息
     */
    public static void notEquals(Object o1, Object o2, String msg) {
        isTrue(ObjUtil.notEqual(o1, o2), msg);
    }

    /**
     * 正则表达式模式：匹配大于 0 的正整数
     */
    public static boolean isPositiveIntegerGreaterThanZero(String str) {
        // 正则表达式模式：匹配大于 0 的正整数
        String pattern = "\\d+";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(str);
        return m.matches() && Integer.parseInt(str) > 0;
    }

    /**
     * 校验是否正整数
     */
    public static void validateIntGt0(String str, String msg) {
        isTrue(isPositiveIntegerGreaterThanZero(str), msg);
    }
    
    // ----------------------------------------------------------------

    /**
     * 校验是否为空白字符串, 是，则抛出异常，提示错误信息
     *
     * @param string  校验字符串
     * @param message 错误信息
     */
    public static void notBlank(String string, String message) {
        isTrue(StrUtil.isNotBlank(string), message);
    }

    /**
     * 校验字符串是否合法，非空且长度符合限定值
     *
     * @param str      字符串
     * @param length   限定值
     * @param paraName 参数名称
     */
    public static void validateStr(String str, int length, String paraName) {
        notBlank(str, paraName + "不能为空");
        isTrue(str.length() <= length, paraName + "长度不能超过" + length + "个字符");
    }

    /**
     * 校验参数ID
     *
     * @param id       ID
     * @param paraName 参数名
     */
    public static void validateId(Long id, String paraName) {
        notNull(id, "参数" + paraName + "不能为空");
        isTrue(id > 0, "参数" + paraName + "不合法");
    }

    public static void validateIdInt(Integer id, String paraName) {
        notNull(id, "参数" + paraName + "不能为空");
        isTrue(id > 0, "参数" + paraName + "不合法");
    }

    /**
     * 校验参数ID
     *
     * @param id       ID
     * @param paraName 参数名
     */
    public static void validateIdStr(String id, String paraName) {
        notNull(id, "参数" + paraName + "不能为空");
    }

    /**
     * 校验分页参数：页码，参数必传
     */
    public static void validatePageNumber(Integer pageNumber) {
        notNull(pageNumber, "缺少参数页码");
        isTrue(pageNumber > 0, "页码错误");
    }

    /**
     * 校验Map是否非空
     *
     * @param map     Map
     * @param message 错误信息
     */
    public static void notEmpty(Map<?, ?> map, String message) {
        isTrue(MapUtil.isNotEmpty(map), message);
    }

    /**
     * 校验集合是否为非空
     *
     * @param arr     数组对象
     * @param message 错误信息
     */
    public static void notEmpty(Object[] arr, String message) {
        isTrue(ArrayUtil.isNotEmpty(arr), message);
    }

    /**
     * 校验是否为数字
     *
     * @param value    数字字符串
     * @param paraName 参数名
     */
    public static void isNumber(String value, String paraName) {
        isTrue(Validator.isNumber(value), paraName + "参数非数字格式");
    }

    /**
     * 校验BigDecimal类型参数 （条件 >= 0）
     *
     * @param decimal  数值
     * @param paraName 参数名
     */
    public static void validateDecimalGe0(BigDecimal decimal, String paraName) {
        notNull(decimal, "缺少" + paraName + "参数");
        isTrue(decimal.compareTo(BigDecimal.ZERO) >= 0, paraName + "参数不合法");
    }

    /**
     * 校验BigDecimal类型参数 （条件 > 0）
     *
     * @param decimal  数值
     * @param paraName 参数名
     */
    public static void validateDecimalGt0(BigDecimal decimal, String paraName) {
        notNull(decimal, "缺少" + paraName + "参数");
        isTrue(decimal.compareTo(BigDecimal.ZERO) > 0, paraName + "参数不合法");
    }

    /**
     * 校验BigDecimal类型参数 （条件 >= 0）
     *
     * @param decimal  数值
     * @param paraName 参数名
     */
    public static void validateNullableDecimalGe0(BigDecimal decimal, String paraName) {
        if (null != decimal) {
            isTrue(decimal.compareTo(BigDecimal.ZERO) >= 0, paraName + "参数不合法");
        }
    }

    /**
     * 校验BigDecimal类型参数 （条件 > 0）
     *
     * @param decimal  数值
     * @param paraName 参数名
     */
    public static void validateNullableDecimalGt0(BigDecimal decimal, String paraName) {
        if (null != decimal) {
            isTrue(decimal.compareTo(BigDecimal.ZERO) > 0, paraName + "参数不合法");
        }
    }

    /**
     * 校验Integer类型参数 （条件 >= 0）
     *
     * @param i        整型数
     * @param paraName 参数名
     */
    public static void validateIntGe0(Integer i, String paraName) {
        notNull(i, "缺少" + paraName + "参数");
        isTrue(i >= 0, paraName + "参数不合法");
    }

    /**
     * 校验Integer类型参数 （条件 > 0）
     *
     * @param i        整型数
     * @param paraName 参数名
     */
    public static void validateIntGt0(Integer i, String paraName) {
        notNull(i, "缺少" + paraName + "参数");
        isTrue(i > 0, paraName + "参数不合法");
    }

    /**
     * 校验年月格式的日期字符串
     *
     * @param monthDate 年月日期，格式: yyyy-MM
     * @param msg       错误信息
     */
    public static void validateNullableMonthDate(String monthDate, String msg) {
        if (StrUtil.isNotBlank(monthDate)) {
            notNull(DateUtil.parse(monthDate, "yyyy-MM"), msg);
        }
    }

    /**
     * 校验年月格式的日期字符串
     *
     * @param date 年月日期，格式: yyyy-MM-dd
     * @param msg  错误信息
     */
    public static void validateNullableDate(String date, String msg) {
        if (StrUtil.isNotBlank(date)) {
            notNull(DateUtil.parseDate(date), msg);
        }
    }

    /**
     * 校验对象是否相等
     *
     * @param o1  对象1
     * @param o2  对象2
     * @param msg 错误信息
     */
    public static void equals(Object o1, Object o2, String msg) {
        isTrue(ObjUtil.equal(o1, o2), msg);
    }


    /**
     * 校验是否为空字符串, 是，则抛出异常，提示错误信息
     *
     * @param str  校验对象
     * @param message 错误信息
     */
    public static void StringIsNull(String str, String message) {
        if (str == null || str.isEmpty()){
            throw new ServiceException(message);
        }
    }

    /**
     * 校验是否为空字符串, 是，则抛出异常，提示错误信息
     *
     * @param str  校验对象
     * @param message 错误信息
     */
    public static void StringIsNull(String[] str, String message) {
        if (str == null || str.length == 0){
            throw new ServiceException(message);
        }
    }

    /**
     * 校验为null，NOT NULL则抛出异常，提示错误信息
     *
     * @param object  校验对象
     * @param message 错误信息
     */
    public static void assertNull(Object object, String message) {
        isTrue(null == object, message);
    }


    public static void isNullCollection(Collection<?> collection,String message){
        if(collection == null || collection.isEmpty()){
            throw new ServiceException(message);
        }
    }

    public static void isNotNullCollection(Collection<?> collection,String message){
        if(collection != null && !collection.isEmpty()){
            throw new ServiceException(message);
        }
    }

    /**
     * 校验是否为null, 是，则抛出异常，提示错误信息
     *
     * @param object  校验对象
     * @param message 错误信息
     */
    public static void isNull(Object object, String message) {
        isTrue(null == object, message);
    }

    /**
     * 校验集合是否为空
     *
     * @param collection 集合对象
     * @param message    错误信息
     */
    public static void isEmpty(Collection<?> collection, String message) {
        isTrue(CollUtil.isEmpty(collection), message);
    }

    /**
     * 校验为空串
     *
     * @param str     字符串
     * @param message 提示信息
     */
    public static void assertBlank(String str, String message) {
        isTrue(StrUtil.isBlank(str), message);
    }
}
